
const { ccclass, property, menu } = cc._decorator;

@ccclass
@menu("ipha组件/跟踪组件")
export default class Ipha_FollowEf extends cc.Component {

    @property({ displayName: "最大速度" })
    private m_SpeedMax: number = 10;

    @property({ displayName: "最小速度" })
    private m_SpeedMin: number = 5;

    @property({ displayName: "转向延迟时间" })
    private m_RotateDelay: number = 0;

    @property({ displayName: "销毁距离" })
    private m_DestroyTargetDis: number = 10;

    private speed: number = 5;

    private moveAngle: number = 0;

    private moveDir: cc.Vec2 = cc.v2(0, 1);

    private tartget: cc.Node = null;

    private rotateSpeed: number = 0.005;
    private readonly rotateSpeedMin: number = 0.01;
    private rotateSpeedMax: number = 0.2;

    private isCanMove: boolean = true;
    private isCanRoate: boolean = false;
    private isArrive: boolean = false;

    onLoad() {

    }

    start() {
        this.scheduleOnce(() => {
            this.isCanRoate = true;
        }, this.m_RotateDelay);
    }

    initData(initDir: number, followTarget: cc.Node) {
        this.moveAngle = initDir;
        this.moveDir = cc.v2(Math.cos(initDir), Math.sin(initDir));
        this.speed = this.m_SpeedMin;
        this.rotateSpeed = this.rotateSpeedMin;
        this.tartget = followTarget;
    }

    followMove(dt: number) {
        if (this.tartget == null) {
            return;
        }
        if (this.isArrive) {
            // this.node.setPosition(this.getTargetPos());
            // this.destroyFollow();
            return;
        }
        if (!this.isCanMove) {
            return;
        }


        if (this.isCanRoate) {
            const tDirV = this._getTargetDirVec();
            this.moveDir.x = cc.misc.lerp(this.moveDir.x, tDirV.x, this.rotateSpeed);
            this.moveDir.y = cc.misc.lerp(this.moveDir.y, tDirV.y, this.rotateSpeed);

            this.rotateSpeed = cc.misc.lerp(this.rotateSpeed, this.rotateSpeedMax, 0.05);
        }

        this.speed = cc.misc.lerp(this.speed, this.m_SpeedMax, 0.01);

        this.node.x += dt * 60 * this.speed * this.moveDir.x;
        this.node.y += dt * 60 * this.speed * this.moveDir.y;


        if (this._getTargetPos().sub(this.node.getPosition()).len() < this.m_DestroyTargetDis) {
            this.isCanMove = false;
            this.isArrive = true;
            this.destroyFollow();
        }
    }

    _getTargetDirVec() {
        const pos = this._getTargetPos();

        return cc.v2(pos.x - this.node.x, pos.y - this.node.y).normalize();
    }

    _getTargetPos() {
        const wPos = this._getTargetWPos();
        return this.node.parent.convertToNodeSpaceAR(wPos);
    }

    _getTargetWPos() {
        return this.tartget.convertToWorldSpaceAR(cc.v2(0, 0));
    }

    destroyFollow() {
        cc.Tween.stopAllByTarget(this.node);
        cc.tween(this.node).to(0.3, { opacity: 0 }).call(() => {
            this.node.destroy();
        }).start();
    }

    protected update(dt: number): void {
        this.followMove(dt);
    }

    protected lateUpdate(dt: number): void {
        // this.followMove(dt);
    }
}
